package pl.edu.pw.polygen.modeler.client.workspace;

import java.util.ArrayList;
import java.util.List;

import pl.edu.pw.polygen.modeler.client.graph.IPropertyChangeListener;
import pl.edu.pw.polygen.modeler.client.graph.VertexModel;
import pl.edu.pw.polygen.modeler.client.object.IPolygenObject;
import pl.edu.pw.polygen.modeler.client.object.Segment;
import pl.edu.pw.polygen.modeler.client.object.Splain;
import pl.edu.pw.polygen.modeler.client.utils.Scale;

public class PolygenContainer {
	private List<IPolygenObject> polygenObjects;
	private List<IPolygenObject> selectedObjects;
	private List<IPolygenObject> holdedObjects;
	private Scale scale;
	
	public PolygenContainer(){
		this.scale = Scale.getInstance();
		this.polygenObjects = new ArrayList<IPolygenObject>();
		this.selectedObjects = new ArrayList<IPolygenObject>();
		this.holdedObjects = new ArrayList<IPolygenObject>();
	}
	
	public void update(){
		for(IPolygenObject o : polygenObjects){
			((IPropertyChangeListener)o).notifyChanges();
		}
	}
	
	public void showBoundaries(){
		for(IPolygenObject o : polygenObjects){
			o.showBoundary();
		}
	}
	
	public void hideBoundaries(){
		for(IPolygenObject o : polygenObjects){
			o.hideBoundary();
		}
	}
	
	public void setSelectable(){
		for(IPolygenObject o : polygenObjects){
			o.setSelectable();
		}
	}	
	
	public void setMergeable(){
		for(IPolygenObject o : polygenObjects){
			o.setMergeable();
		}
	}
	
	public void setLocked(){
		for(IPolygenObject o : polygenObjects){
			o.setLocked();
		}
	}
	
	public void add(IPolygenObject o){
		if(polygenObjects.contains(o)==false){
			polygenObjects.add(o);
		}
	}
	
	public void remove(IPolygenObject o){
		if(polygenObjects.contains(o)){
			polygenObjects.remove(o);
		}
	}
	
	public void clearObjects(){
		polygenObjects.clear();
	}
	
	public void addToSelected(IPolygenObject o){
		if(selectedObjects.contains(o)==false){
			selectedObjects.add(o);
		}
	}
	
	public void removeFromSelected(IPolygenObject o){
		if(selectedObjects.contains(o)){
			selectedObjects.remove(o);
		}
	}
	
	public void clearSelectedObjects(){
		selectedObjects.clear();
	}
	
	public void addToHolded(IPolygenObject o){
		if(holdedObjects.contains(o)==false){
			this.holdedObjects.add(o);
		}
	}
	
	public void removeFromHolded(IPolygenObject o){
		if(holdedObjects.contains(o)){
			this.holdedObjects.remove(o);
		}
	}
	
	public void clearHoldedObjects(){
		this.holdedObjects.clear();
	}
	
	public void clearAll(){
		this.clearObjects();
		this.clearSelectedObjects();
		this.clearHoldedObjects();
	}
	
	//Getters and setters
	
	public List<IPolygenObject> getPolygenObjects() {
		return polygenObjects;
	}

	public List<IPolygenObject> getSelectedObjects() {
		return selectedObjects;
	}

	public List<IPolygenObject> getHoldedObjects() {
		return holdedObjects;
	}

	public boolean contains(IPolygenObject o) {
		return polygenObjects.contains(o);
	}

	public void selectObjects(double x1, double y1, double x2, double y2) {
		this.clearSelectedObjects();
		for(IPolygenObject o : polygenObjects){
			if(o.getModel() instanceof VertexModel){
				VertexModel vm = (VertexModel)o.getModel();
				if(x1 < vm.getX() && y1 < vm.getY() && vm.getX() < x2 && vm.getY()<y2){
					o.select();
				}
			}
		}
		
		for(IPolygenObject o : polygenObjects){
			if(o instanceof Segment){
				if(((Segment) o).getBeginVertex().isSelected() && ((Segment) o).getEndVertex().isSelected()){
					o.select();
				}
			}else if(o instanceof Splain){
				if(((Splain) o).getBeginVertex().isSelected() && ((Splain) o).getEndVertex().isSelected()){
					o.select();
				}
			}
		}
	}
		
	public void shiftSelectedObjects(double dx, double dy) {
		for(IPolygenObject o : selectedObjects){
			if(o.getModel() instanceof VertexModel){
				VertexModel vm = (VertexModel)o.getModel();
				double x = vm.getX();
				double y = vm.getY();
				x+=dx;
				y+=dy;
				vm.setPosition(x, y);
			}
		}
	}
	

}
